(() => {

  class Animal {
    name: string

    constructor (name: string) {
      this.name = name
    }

    run (distance: number=0) {
      console.log(this.name, 'run ', distance)
    }
  }

  class Snake extends Animal {
    run (distance: number=5) {
      console.log('snake run')
      super.run(distance)
    }
  }

  class Horse extends Animal {
    run (distance: number=15) {
      console.log('horse run')
      super.run(distance)
    }

    xxx () {
      console.log('horse xxx()')
    }
  }


  const a: Animal = new Animal('a1')
  a.run()

  function test(a: Animal) {
    a.run()
  }

  test(a)
  test(new Snake('s1'))
  test(new Horse('h1'))

  /* 
  声明父类型引用, 调用对象的方法
  而传入的值是某个子类型的实例, 调用的对象的方法子类型对象的方法
  ----> 多态
  */

  const a2: Animal = new Horse('h2')
  // a2.xxx() // 不能通过父类型引用调用具体子类型特有的方法

})()